const crypto = require("crypto");

var exportOperator = function (operator) {
    @dump(operator);
    return {
        id       : operator.id,
        ouid     : operator.ouid,
        account  : operator.account,
        name     : operator.name,
        icon     : operator.icon,
        identity : operator.identity,
        access   : operator.access,
        is_admin : operator.is_admin
    }
}

var checkPassword = function (operator, password) {
    return operator.password == crypto.createHash('sha256').update(password + operator.salt).digest().toString("base64")
}

/**
 * 可以把相关的检查做在这里；
 */
var setupPassword = function (lab, operator, password) {

    if (password.length < 6) {
        throw @lab.errors.password_length;
    }
    operator.salt = @.uuid();
    operator.password = crypto.createHash('sha256').update(password + operator.salt).digest().toString("base64");

    return @.async(function () {

        if (lab) {
            lab.update("backend_operators", operator).pipe(this);
        } else {
            this.next(operator);
        }

    }).then(function (updated_operator) {

        if (lab) {
            this.next(exportOperator(updated_operator));
        } else {
            this.next(updated_operator);
        }

    })
};

// TODO : https://github.com/bin-y/standard-ecies#readme what the fuck
var certToPEM = function(header, body) {
    var pemBuffer = ["-----BEGIN " + header + "-----"];
    for (;;) {
        pemBuffer.push(body.substr((pemBuffer.length - 1) * 64, 64));
        if ((pemBuffer.length - 1) * 64 >= body.length) {
            break;
        }
    }
    pemBuffer.push("-----END " + header + "-----");
    return pemBuffer.join("\n");
}
var generateKeyAndID = function (id) {

    var generateID = id || @.uuid(true);
    var digest = crypto.createHash('sha256').update(generateID).digest();

    var keypair = crypto.generateKeyPairSync('rsa', {
        modulusLength: 1024,
        publicKeyEncoding: {
            type: 'spki',
            format: 'der'
        },
        privateKeyEncoding: {
            type: 'pkcs1',
            format: 'der'
        }
    });

    var signer = crypto.createSign("RSA-SHA1");
    signer.write(digest);
    signer.end();

    var privateKeyBuffer64 = keypair.privateKey.toString("base64");
    var publicKeyBuffer64  = keypair.publicKey.toString("base64");

    return {
        "id": generateID,
        "signature": signer.sign(certToPEM("RSA PRIVATE KEY",privateKeyBuffer64), "base64"),
        "public_key": publicKeyBuffer64,
        "private_key": publicKeyBuffer64
    };
}

var signWithKeyAndID = function (id, key) {

    var signer = crypto.createSign("RSA-SHA1");
    signer.write(crypto.createHash('sha256').update(id).digest());
    signer.end();
    return signer.sign(certToPEM("RSA PRIVATE KEY",key), "base64");
};


var verifyKeyAndID = function (id, key, signature) {

    var verifier = crypto.createVerify("RSA-SHA1");
    verifier.update(crypto.createHash('sha256').update(id).digest());
    return verifier.verify(certToPEM("PUBLIC KEY",key), signature, "base64");

};

var createKeyAndID = function (lab, session) {

    var keyAndID = generateKeyAndID();
    session.participantID = keyAndID.id;

    return lab.create("backend_participants", {

        id                : keyAndID.id,
        public_key        : keyAndID.public_key,
        last_participant  : Date.now(),
        uid               : session.currentUser ? session.currentUser.id : null,
        user_ip           : session && session.connection  ? session.connection.remoteAddress : null

    }).resolve({
        "id"        : keyAndID.id,
        "key"       : keyAndID.public_key,
        "signature" : keyAndID.signature
    });
}



module.exports = {
    exportOperator : exportOperator,
    checkPassword  : checkPassword,
    setupPassword  : setupPassword,
    createKeyAndID   : createKeyAndID,
    verifyKeyAndID   : verifyKeyAndID,
    generateKeyAndID : generateKeyAndID
}